import Result from './domain/vo/Result.js'
import { preHandler } from './interceptor/GlobalInterceptor.js'
import LwtUtils from './utils/LwtUtils.js'
import AuthProperties from './properties/AtuhProperites.js'

// 不太会玩JS，干脆直接用个map模拟一下好了
import { buildController as buildUserController } from './controller/UserController.js'
import { buildController as buildCourseController } from './controller/CourseController.js'



// 这里是一个巨大的东西
// 包含了 只有一个过滤器的过滤器链、根据路径调用函数、参数自动装配、甚至还有全局异常处理器

// 每个构造器会返回一个地址和controller函数的对应关系
const controllerList = [
    buildUserController,
    buildCourseController
]
const urlMap = new Object()

// 初始化 url和controller的映射
controllerList.forEach(controller => {
    const obj = controller()
    for (let url in obj) {
        urlMap[url] = obj[url]
    }
})


export const get = (obj) => {
    // 解析URL参数
    const url = String(obj.url)
    if (!url) {
        return
    }

    const data = new Object()
    const paramIndex = url.indexOf("?")
    const param = url.substring(paramIndex + 1)

    if (paramIndex != -1) {
        obj.url = url.substring(0, url.indexOf("?"))
    }

    param.split("&").forEach(item => {
        const arr = item.split("=")
        data[arr[0]] = arr[1]
    })

    return new Promise((resolve, reject) => {
        try {
            resolve(execControler(Object.assign(obj, {
                data: data
            })))
        }catch(e) {
            reject(e)
        }
    })

}

export const post = (obj) => {
    return new Promise((resolve, reject) => {
        try {
            resolve(execControler(obj))
        }catch(e) {
            reject(e)
        }
    })
    
}


function execControler(request) {
    
    if (!request || !request.url) {
        throw new Error("invalid url")
    }
    
    // 懒得做链式的拦截器了，简单处理一下啦
    if (!preHandler(request, null, null)) {
        // 鉴权不通过
        return Result.error("未登录或登录已过期...")
    }

    // 解析token
    let claims = new Object()
    try {
        claims = LwtUtils.parser.setSignature(AuthProperties.lwtKey).parse(request.header.token).getClamins()
    }catch(e) {
        // 不用做异常处理，在这里意味着是不需要鉴权的api
    }
    
    const url = request.url
    if (!urlMap[url]) {
        throw new Error("url invalid")
    }

    // 参数自动装配？
    const method = urlMap[url]
    
    const str = method.toString()

    let params = null
    let paramsMatch = str.match(/function.*\((.*?)\)/)
    if (!paramsMatch) {
        // 尝试箭头函数来匹配
        paramsMatch = str.match(/\((.*?)\).*=>/)
    }
    if (paramsMatch) {
        params = String(paramsMatch[1]).replace(" ", "").split(",")
    }
    
    console.log("parse params = ", params, str)
    try {
        if (params) {
            const paramMap = new Object()
            for (let i in request.data) {
                paramMap[i] = request.data[i]
            }
    
            const args = []
            params.forEach(param => {
                param = param.replace(/^\s*|\s*$/g, "") //去除首尾空格
                
                if (paramMap.hasOwnProperty(param)) {
                    args.push(paramMap[param])
                }else if(claims.hasOwnProperty(param)) {
                    // 没有线程上下文，直接把token的参数也算作啦
                    args.push(claims[param])
                }else {
                    args.push(null)
                }
            })
    
            return method.apply(null, args)
        }
    }catch(e) {
        console.log(e)
        return Result.error(e.message)
    }


}